﻿#include "../head/menu.hh"
#include "../head/tools.hh"
#include <iostream>
#include <fstream>

void Menu::showMainMenu() {
    std::cout << "===== Banking System =====\n";
    std::cout << "1. Register new customer\n";
    std::cout << "2. Access customer accounts\n";
    std::cout << "3. Display all bank accounts\n";
    std::cout << "4. Transaction reports\n";
    std::cout << "5. Exit\n";
    std::cout << "Please choose: ";
}

void Menu::registerCustomer() {
    system("cls");
    std::string name;
    std::cout << "===== Register New Customer =====\n";
    std::cout << "Enter customer name: ";
    std::getline(std::cin, name);

    bank.addCustomer(name);
    system("pause");
    system("cls");
}

void Menu::displayAllBankAccounts() const {
    system("cls");
    bank.showAllAccounts();
    system("pause");
    system("cls");
}

void Menu::generateTransactionReport() {
    std::string reportname = "./report/transactions_" + tools::gettime() + ".txt";
    std::ofstream report(reportname);
    if (report.is_open()) {
        // 获取所有客户的交易记录
        for (const auto& customer : bank.getCustomers()) {
            // 输出客户的基本信息
            report << "Customer: " << customer->getName() << std::endl;

            // 输出支票账户的交易记录
            report << "Checking Account Transactions:" << std::endl;
            customer->getCheckingAccount()->showTransactions(report); // 调用 showTransactions

            // 输出储蓄账户的交易记录
            report << "Savings Account Transactions:" << std::endl;
            customer->getSavingsAccount()->showTransactions(report); // 调用 showTransactions

            // 为每个客户的报告添加一个空行
            report << std::endl;
        }
        report.close();
        std::cout << "===== Transaction Reports =====\n";
        std::cout << "System response:\n";
        std::cout << "Report successfully generated as \"" << reportname <<"\"\n";
        std::cout << "All transactions have been saved in chronological order.\n";
    }
    system("pause");
    system("cls");
}


void Menu::accessCustomerAccounts() {
    system("cls");
    std::string name;
    std::cout << "===== Access Customer Accounts =====\n";
    std::cout << "Enter customer name: ";
    std::getline(std::cin, name);

    Customer* customer = bank.findCustomer(name);
    if (customer) {
        // 提供进一步的选项
        showCustomerOptions(customer);
    }
    else {
        std::cout << "Customer not found.\n";
        system("pause");
        system("cls");
    }
}

void Menu::showCustomerOptions(Customer* customer) {
    std::string choice;
    while(true){

        system("cls");
        std::cout << "===== Customer: " << customer->getName() << " =====\n";
        std::cout << "This customer has the following accounts:\n";
        std::cout << "1. Savings  Account: " << customer->getSavingsAccount()->getAccountId()
            << "\n   Balance: ￥" << customer->getSavingsAccount()->showBalance() << "\n";
        std::cout << "2. Checking Account: " << customer->getCheckingAccount()->getAccountId()
            << "\n   Balance: ￥" << customer->getCheckingAccount()->showBalance() << "\n";

        std::cout << "\nOptions:\n";
        std::cout << "1. Access Savings Account\n";
        std::cout << "2. Access Checking Account\n";
        std::cout << "3. View all transactions for this customer\n";
        std::cout << "4. Generate customer report\n";
        std::cout << "5. Return to main menu\n";
        std::cout << "Please choose: ";
        std::getline(std::cin, choice);
        if (choice.length() != 1) {
            std::cout << "Invalid choice, please try again.\n";
            system("pause");
            system("cls");
            continue;
        }

        switch (choice[0]) {
        case '1':
            accessAccount(customer->getSavingsAccount());
            break;
        case '2':
            accessAccount(customer->getCheckingAccount());
            break;
        case '3':
            viewTransactions(customer);
            break;
        case '4':
            generateCustomerReport(customer);
            break;
        case '5':
            std::cout << "Returning to main menu...\n";
            system("pause");
            system("cls");
            return;
        default:
            std::cout << "Invalid choice, please try again.\n";
            system("pause");
            system("cls");
        }
    }
}

void Menu::accessAccount(Account* account) {
    system("cls");
    // 显示账户基本信息
    if (auto* checkingAccount = dynamic_cast<CheckingAccount*>(account)) {
        showCheckingAccountOptions(checkingAccount);
    }
    else if (auto* savingsAccount = dynamic_cast<SavingsAccount*>(account)) {
        showSavingsAccountOptions(savingsAccount);
    }
}

void Menu::viewTransactions(Customer* customer) {
    system("cls");
    std::cout << "Viewing transactions for customer: " << customer->getName() << std::endl;
    std::cout << "Savings Account Transactions:\n";
    customer->getSavingsAccount()->showTransactions(std::cout);

    std::cout << "\n";

    std::cout << "Checking Account Transactions:\n";
    customer->getCheckingAccount()->showTransactions(std::cout);
    system("pause");
}

void Menu::generateCustomerReport(Customer* customer) {
    std::string reportname = "./report/transactions_" + customer->getName() + "_" + tools::gettime() + ".txt";
    std::ofstream report(reportname);
    if (report.is_open()) {
        report << "Customer Report for: " << customer->getName() << "\n";
        report << "Savings  Account Balance: ￥" << customer->getSavingsAccount()->showBalance() << "\n";
        report << "Checking Account Balance: ￥" << customer->getCheckingAccount()->showBalance() << "\n";

        report << "\nTransactions:\n";

        std::cout << "Savings Account Transactions:\n";
        customer->getSavingsAccount()->showTransactions(report);

        std::cout << "\n";

        std::cout << "Checking Account Transactions:\n";
        customer->getCheckingAccount()->showTransactions(report);

        report.close();
        std::cout << "Customer report generated successfully!\n";
    }
    system("pause");
    system("cls");
}

void Menu::showCheckingAccountOptions(CheckingAccount* account) {
    std::string choice;
    while(true){
        account->showinfo();
        std::cout << "\n1. Deposit\n";
        std::cout << "2. Withdraw\n";
        std::cout << "3. Transfer\n";
        std::cout << "4. View transaction history\n";
        std::cout << "5. Generate bank account report\n";
        std::cout << "6. Return to customer page\n";
        std::cout << "Please choose: ";
        std::getline(std::cin, choice);

        if (choice.length() != 1) {
            std::cout << "Invalid choice, please try again.\n";
            system("pause");
            system("cls");
            continue;
        }

        switch (choice[0]) {
        case '1':
            depositToAccount(account);
            break;
        case '2':
            withdrawFromAccount(account);
            break;
        case '3':
            transferFromAccount(account);
            break;
        case '4':
            viewTransactionHistory(account);
            break;
        case '5':
            generateAccountReport(account);
            break;
        case '6':
            std::cout << "Returning to customer page...\n";
            system("pause");
            system("cls");
            return ;
        default:
            std::cout << "Invalid choice, please try again.\n";
            system("pause");
            system("cls");
        }
    }
}

void Menu::showSavingsAccountOptions(SavingsAccount* account) {
    std::string choice;
    while(true) {
        account->showinfo();
        std::cout << "\n1. Transfer\n";
        std::cout << "2. View transaction history\n";
        std::cout << "3. Generate bank account report\n";
        std::cout << "4. Return to customer page\n";
        std::cout << "Please choose: ";
        std::getline(std::cin, choice);
        if (choice.length() != 1) {
            std::cout << "Invalid choice, please try again.\n";
            system("pause");
            system("cls");
            continue;
        }

        switch (choice[0]) {
        case '1':
            transferFromAccount(account);
            break;
        case '2':
            viewTransactionHistory(account);
            break;
        case '3':
            generateAccountReport(account);
            break;
        case '4':
            std::cout << "Returning to customer page...\n";
            system("pause");
            system("cls");
            return ;
        default:
            std::cout << "Invalid choice, please try again.\n";

            system("pause");
            system("cls");
        }
    }
}

void Menu::depositToAccount(CheckingAccount* account) {
    long long  amount;
    std::string amountstr;
    std::string note;

    do {
        system("cls");
        std::cout << "===== Deposit to Account: " << account->getAccountId() << " =====\n";
        std::cout << "Current Balance: ￥" << account->showBalance() << "\n";
        std::cout << "Enter amount to deposit: ";
        std::getline(std::cin, amountstr);
        amount = tools::amountchange(amountstr);
        if (amount == -1) {
            std::cout << "Error Amount !\nPlease Input Again !\n";
            system("pause");
        }
    } while (amount == -1);

    std::cout << "Add note (optional): ";
    std::getline(std::cin, note);

    // 执行存款操作
    bool flag = account->deposit(amount, note);

    // 输出存款结果
    if (flag) {
        std::cout << "System response:\n";
        std::cout << "Deposit successful!\n";
        std::cout << "New balance: ￥" << account->showBalance() << "\n";
        std::cout << "Transaction ID: T" << account->getTransactions().size() << " has been recorded.\n";
    }
    else {
        std::cout << "System response:\n";
        std::cout << "Deposit Failed!\n";
    }

    system("pause");
    system("cls");
}

void Menu::withdrawFromAccount(CheckingAccount* account) {
    long long  amount;
    std::string amountstr;
    std::string note;
    
    do {
        system("cls");
        std::cout << "===== Withdraw to Account: " << account->getAccountId() << " =====\n";
        std::cout << "Current Balance: ￥" << account->showBalance() << "\n";
        std::cout << "Enter amount to withdraw: ";
        
        std::getline(std::cin, amountstr);
        amount = tools::amountchange(amountstr);
        if (amount == -1) {
            std::cout << "Error Amount !\nPlease Input Again !\n";
            system("pause");
        }
    } while (amount == -1);

    std::cout << "Add note (optional): ";
    std::getline(std::cin, note);

    // 执行取款操作
    bool flag = account->withdraw(amount, note);

    // 输出取款结果
    if (flag) {
        std::cout << "System response:\n";
        std::cout << "Withdrawal Successful!\n";
        std::cout << "New balance: ￥" << account->showBalance() << "\n";
        std::cout << "Transaction ID: T" << account->getTransactions().size() << " has been recorded.\n";
    }
    else {
        std::cout << "System response:\n";
        std::cout << "Withdrawal Failed: Insuffuice Amount!\n";
    }

    system("pause");
    system("cls");
}

void Menu::transferFromAccount(Account* account) {
    std::string destinationAccountId;
    long long  amount;
    std::string amountstr;
    std::string note;
    Account* destinationAccount = nullptr;
    do {
        system("cls");
        std::cout << "===== Transfer from Account: " << account->getAccountId() << " =====\n";
        std::cout << "Current Balance: ￥" << account->showBalance() << "\n";
        std::cout << "Enter destination account ID: ";
        std::getline(std::cin, destinationAccountId);

        destinationAccount = bank.findAccountById(destinationAccountId);

        if (!destinationAccount || destinationAccountId == account->getAccountId()) {
            std::cout << "Account not found.\n";
            std::cout << "Transfer failed.\n";
            system("pause");
            system("cls");
            return;
        }
        if (auto* savingsAccount = dynamic_cast<SavingsAccount*>(account)) {
            Customer* customer = bank.findCustomerByAccount(account);  // 查找客户
            CheckingAccount* destinationCheckingAccount = customer->getCheckingAccount();
            if (destinationAccount != destinationCheckingAccount) {
                std::cout << "Savings account can only transfer to the same customer's checking account.\n";
                system("pause");
                system("cls");
                return;
            }
        }
    } while (destinationAccount == nullptr);
    do {
        system("cls");
        std::cout << "===== Transfer from Account: " << account->getAccountId() << " =====\n";
        std::cout << "Current Balance: ￥" << account->showBalance() << "\n";
        std::cout << "Destination Account ID: " << destinationAccountId << "\n";
        std::cout << "Enter amount to transfer: ";
        std::getline(std::cin, amountstr);
        amount = tools::amountchange(amountstr);
        if (amount == -1) {
            std::cout << "Error Amount !\nPlease Input Again !\n";
            system("pause");
        }
    } while (amount == -1);
    std::cout << "Add note (optional): ";

    // 执行转账
    bool flag = account->transfer(amount, destinationAccount, note);

    // 输出转账结果
    if (flag) {
        std::cout << "System response:\n";
        std::cout << "Transfer successful!\n";
        std::cout << "New balance: ￥" << account->showBalance() << "\n";
        std::cout << "Transaction ID: T" << account->getTransactions().size() << " has been recorded.\n";
    }
    else {
        std::cout << "System response:\n";
        std::cout << "Transfer Failed: Insuffuice Amount!\n";
    }

    system("pause");
    system("cls");
}

void Menu::viewTransactionHistory(Account* account) {
    system("cls");
    std::cout << "===== Transaction History for Account: " << account->getAccountId() << " =====\n";
    account->showTransactions(std::cout);
    system("pause");
    system("cls");
}

void Menu::generateAccountReport(Account* account) {
    std::string reportname = "./report/transactions_" + account->getAccountId() + "_" + tools::gettime() + ".txt";
    std::ofstream report(reportname);
    if (report.is_open()) {
        report << "Bank Account Report for: " << account->getAccountId() << "\n";
        report << "Account holder: " << account->getAccountHolder() << "\n";
        report << "Balance: ￥" << account->showBalance() << "\n";

        report << "\nTransactions:\n";
        account->showTransactions(report);

        report.close();
        std::cout << "Account report generated successfully!\n";
    }
    system("pause");
    system("cls");
}